#include "getPosition.hpp"

/*Napi::Value GetPosition(const Napi::CallbackInfo &info)
{
  Napi::Env env = info.Env();
  // winrt::init_apartment();
  Geolocator geolocator;
  auto promise = Napi::Promise::Deferred::New(env);
  auto feedOp{ [env, promise, geolocator](){
    auto positionAsync = geolocator.GetGeopositionAsync();
    try
    {
      Napi::Object result = Napi::Object::New(env);
      auto asyncResult = positionAsync.get(); // 阻塞直到获取完成
      BasicGeoposition position = asyncResult.Coordinate().Point().Position();
      // std::cout << "Geoposition retrieved. position: " << position.Latitude << "," << position.Longitude << std::endl;
      result.Set("latitude", position.Latitude);
      result.Set("longitude", position.Longitude);
      promise.Resolve(result);
      // 可以进一步处理 position
    }
    catch (const hresult_error &e)
    {
      // 捕获异常并传递错误信息
      std::string errorMessage = winrt::to_string(e.message());
      //std::cout << "Error occurred: " << errorMessage << std::endl;
      promise.Reject(Napi::String::New(promise.Env(), errorMessage));
    }
  }};
  feedOp();
  return promise.Promise();
}*/

// 线程安全函数调用回调
void TSFN_Callback(Napi::Env env, Napi::Promise::Deferred deferred, GeopositionData *data)
{
  if (env != nullptr && data != nullptr)
  {
    if (data->error.empty())
    {
      // 成功获取地理位置，返回对象
      Napi::Object result = Napi::Object::New(env);
      result.Set("latitude", data->latitude);
      result.Set("longitude", data->longitude);
      deferred.Resolve(result);
    }
    else
    {
      // 处理错误
      deferred.Reject(Napi::String::New(env, data->error));
    }
  }
  delete data; // 清理传递的数据
}

Napi::Value GetPosition(const Napi::CallbackInfo &info)
{
  Napi::Env env = info.Env();
  Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);

  // 创建线程安全函数
  Napi::ThreadSafeFunction tsfn = Napi::ThreadSafeFunction::New(
      env,
      Napi::Function::New(env, [](const Napi::CallbackInfo &) {}), // 占位回调
      "GeolocationTSFN",
      0, // 队列限制
      1  // 线程数
  );

  // 启动异步线程来获取位置
  std::thread([tsfn, deferred]() mutable {
        Geolocator geolocator;

        try {
            auto positionAsync = geolocator.GetGeopositionAsync();
            auto asyncResult = positionAsync.get();  // 阻塞等待结果
            BasicGeoposition position = asyncResult.Coordinate().Point().Position();
            //打印位置信息
            //std::cout << "Geoposition retrieved. position: " << position.Latitude << "," << position.Longitude << std::endl;
            // 创建并填充数据
            GeopositionData* data = new GeopositionData(position.Latitude, position.Longitude, "");

            // 调用线程安全函数，将结果传递回主线程
            tsfn.BlockingCall(data, [deferred](Napi::Env env, Napi::Function jsCallback, GeopositionData* data) {
              TSFN_Callback(env, deferred, data);
            });
        } catch (const hresult_error& e) {
            // 捕获异常并传递错误信息
            std::string errorMessage = winrt::to_string(e.message());
            //std::cout << "Error occurred: " << errorMessage << std::endl;
            GeopositionData* data = new GeopositionData(0.0, 0.0, errorMessage);

            tsfn.BlockingCall(data, [deferred](Napi::Env env, Napi::Function jsCallback, GeopositionData* data) {
              TSFN_Callback(env, deferred, data);
            });
        }

        // 关闭线程安全函数
        tsfn.Release(); 
  }).detach();

  return deferred.Promise();
}

Napi::Object Init(Napi::Env env, Napi::Object exports)
{

  exports.Set(Napi::String::New(env, "GetPosition"), Napi::Function::New(env, GetPosition));
  return exports;
}

NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)